<?php


namespace App\servers;


use Elasticsearch\ClientBuilder;

class EsServer
{
    private static $client = null;

    private function __construct()
    {
        $host = [
            config('es.host')
        ];
        self::$client = ClientBuilder::create()
                    ->setHosts($host)
                    ->build();
    }


    private function __clone()
    {
        // TODO: Implement __clone() method.
    }

    /**
     * 入口
     */
    public static function Entrance()
    {
        if(self::$client == null){
            self::$client = new EsServer();
        }
        return  self::$client;
    }

    /**
     * 判断索引是否存在
     * @param string $index_name
     * @return bool|mixed|string
     */
    public function exists_index($index_name = 'test_ik')
    {
        $params = [
            'index' => $index_name
        ];
        try {
            return self::$client->indices()->exists($params);
        } catch (\Elasticsearch\Common\Exceptions\BadRequest400Exception $e) {
            $msg = $e->getMessage();
            $msg = json_decode($msg,true);
            return $msg;
        }
    }

    /**
     * 创建索引
     * @param string $index_name
     * @return array|mixed|string
     */
    public function create_index($index_name = 'test_ik') { // 只能创建一次
        $params = [
            'index' => $index_name,
            'body' => [
                'settings' => [
                    'number_of_shards' => 5,
                    'number_of_replicas' => 1
                ]
            ]
        ];
        try {
            return self::$client->indices()->create($params);
        } catch (\Elasticsearch\Common\Exceptions\BadRequest400Exception $e) {
            $msg = $e->getMessage();
            $msg = json_decode($msg,true);
            return $msg;
        }
    }

    /**
     * 删除索引
     * @param string $index_name
     * @return array
     */
    public function delete_index($index_name = 'test_ik') {
        $params = ['index' => $index_name];
        $response = self::$client->indices()->delete($params);
        return $response;
    }

    /**
     * 添加文档
     * @param $id
     * @param $doc ['id'=>100, 'title'=>'phone']
     * @param string $index_name
     * @param string $type_name
     * @return array
     */
    public function add_doc($id,$doc,$index_name = 'test_ik') {
        $params = [
            'index' => $index_name,
            'id' => $id,
            'body' => $doc
        ];
        dd(self::$client);
        $response = self::$client->index($params);
        return $response;
    }

    /**
     * 判断文档存在
     * @param int $id
     * @param string $index_name
     * @param string $type_name
     * @return array|bool
     */
    public function exists_doc($id = 1,$index_name = 'test_ik',$type_name = '_doc') {
        $params = [
            'index' => $index_name,
            'type' => $type_name,
            'id' => $id
        ];
        $response = self::$client->exists($params);
        return $response;
    }

    /**
     * 获取文档
     * @param int $id
     * @param string $index_name
     * @param string $type_name
     * @return array
     */
    public function get_doc($id = 1,$index_name = 'test_ik',$type_name = '_doc') {
        $params = [
            'index' => $index_name,
            'type' => $type_name,
            'id' => $id
        ];
        $response = self::$client->get($params);
        return $response;
    }

    /**
     * 更新文档
     * @param int $id
     * @param string $index_name
     * @param string $type_name
     * @param array $body ['doc' => ['title' => '苹果手机iPhoneX']]
     * @return array
     */
    public function update_doc($id = 1,$index_name = 'test_ik',$type_name = '_doc', $body=[]) {
        // 可以灵活添加新字段,最好不要乱添加
        $params = [
            'index' => $index_name,
            'type' => $type_name,
            'id' => $id,
            'body' => $body
        ];
        $response = self::$client->update($params);
        return $response;
    }

    /**
     * 删除文档
     * @param int $id
     * @param string $index_name
     * @param string $type_name
     * @return array
     */
    public function delete_doc($id = 1,$index_name = 'test_ik',$type_name = '_doc') {
        $params = [
            'index' => $index_name,
            'type' => $type_name,
            'id' => $id
        ];
        $response = self::$client->delete($params);
        return $response;
    }

    /**
     * 搜索文档 (分页，排序，权重，过滤)
     * @param string $index_name
     * @param string $type_name
     * @param array $body
     * @return array
     */
    public function search_doc($body=[],$index_name = "test_ik",$type_name = "_doc") {
        $params = [
            'index' => $index_name,
            'type' => $type_name,
            'body' => [
                'query' => [
                    'match' => $body
                ]
            ]
        ];

        $results = self::$client->search($params);
        return $results;
    }

    /**
     * 分页搜索
     * @name lzh
     * @param int $page
     * @param int $limit
     * @param array $body
     * @param string $index_name
     * @param string $type_name
     * @return array|callable
     */
    public function search_page($page=0,$limit=10,$body=[],$index_name = "test_ik",$type_name = "_doc") {
        $params = [
            'index' => $index_name,
            'type' => $type_name,
            'body' => [
                'from'=> $page,
                'size'=>$limit,
                'query' => [
                    'match' => $body
                ],
                "sort"=>[
                    ["id"=>["order"=>"desc"]]
                ],
                'highlight' => [
                    'pre_tags' => ["<em style='color: #ff0000'>"],
                    'post_tags' => ["</em>"],
                    'fields'=>['building_name'=>new \stdClass()]
                ]
            ]
        ];
        $results = self::$client->search($params);
        return $results;
    }

    /**高亮
     * @return void
     */
    public function heightLight($index_name,$field,$search){
        $params=[
            'index'=>$index_name,
            'body'=>[
                'query'=>[
                    'match'=>[
                        $field=>$search
                    ],
                ],
                'highlight' => [
                    'pre_tags' => ["<em style='color: red'>"],
                    'post_tags' => ["</em>"],
                    'fields'=>["property_name"=>new \stdClass()]
                ]
            ],
        ];
        $response=self::$client->search($params);
        $data=$response['hits']['hits'];
        return $data;
    }

    public function search_all($page=0,$limit=10,$index_name = "test_ik",$type_name = "_doc"){
        $params = [
            'index' => $index_name,
            'type' => $type_name,
            'body' => [
                'from'=> $page,
                'size'=>$limit,
                'query' => [
                    "match_all"=>(object)[]
                ],
                "sort"=>[
                    ["id"=>["order"=>"desc"]]
                ],
                'highlight' => [
                    'pre_tags' => ["<em style='color: #ff0000'>"],
                    'post_tags' => ["</em>"],
                    'fields'=>['building_name'=>new \stdClass()]
                ]
            ]
        ];
        $results = self::$client->search($params);
        return $results;
    }
}
